<?php

use Mapper\MemberModel as MemberMapper;
use Mapper\MemberSwitchModel as MemberSwitchMapper;

class MemberController extends \Base\ApiController {

    public $genderArr = [
        '男' => 1,
        '女' => 2,
    ];

    /**
     * @desc 注册功能-第一步
     *
     * @return false
     */
    public function registerAction() {
        $request  = $this->getRequest();
        $mobile   = (string)$request->get('mobile');
        $password = (string)$request->get('password');
        $code     = (string)$request->get('code');

        if(empty($mobile)) {
            return \Response::error('手机号码不能为空', 10111);
        }

        if(empty($password)) {
            return \Response::error('密码不能为空', 10112);
        }

        if(empty($code)) {
            return \Response::error('验证码不能为空, 请重新输入', 10108);
        }

        if(!\Lib\Is::mobileNum($mobile)) {
            return \Response::error('手机号码格式错误', 10107);
        }

        $verifyCode = \Lib\Msgcode::verify($mobile, 'register', $code);

        if(!$verifyCode) {
            return \Response::error('验证码错误', 10109);
        }

        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findByMobile($mobile);

        if($memberModel instanceof \MemberModel) {
            return \Response::error('手机号已存在, 请重新输入', 10102);
        }

        return \Response::data(null, '注册第一步成功');
    }

    /**
     * @desc 注册功能-完善资料
     *
     * @return false
     */
    public function firstCompleteInfoAction() {
        $request  = $this->getRequest();
        $mobile   = (string)$request->get('mobile');
        $password = (string)$request->get('password');
        $nickname = (string)$request->get('nickname');
        $gender   = (string)$request->get('gender');
        $birthday = (string)$request->get('birthday');
        $birthday = strtotime($birthday);

        if(empty($mobile)) {
            return \Response::error('手机号码不能为空', 10111);
        }

        if(empty($password)) {
            return \Response::error('密码不能为空', 10112);
        }

        if(empty($nickname)) {
            return \Response::error('昵称不能为空', 10115);
        }

        if(empty($birthday)) {
            return \Response::error('生日不能为空', 10117);
        }

        $gender = isset($this->genderArr[$gender]) ? $this->genderArr[$gender] : 0;

        if(empty($gender)) {
            return \Response::error('性别不能为空', 10116);
        }

        $registerTime = time();
        $openId       = $this->createOpenId($nickname, $registerTime);

        $model           = new \MemberModel;
        $memberMapper    = MemberMapper::getInstance();
        $encryptPassword = \Lib\Passwd::encrypt($password);
        $model->setNick_name(urlencode($nickname));
        $model->setLetter(\Lib\Pinyin::to_first($nickname));
        $model->setGender($gender);
        $model->setBirthday($birthday);
        $model->setMobile($mobile);
        $model->setPassword($encryptPassword);
        $model->setStatus(\Lib\Consts::LOGIN_STATUS_NORMAL);
        $model->setRegist_time($registerTime);
        $model->setOpen_id($openId);

        try {
            $id = $memberMapper->insert($model);

            if($id <= 0) {
                return \Response::error('注册失败', 10123);
            }

            // 注册成功后, 即直接登录
            $userLib = \Lib\User::getInstance();
            $userLib->login($mobile, $password);
            $token = \Lib\Token::getInstance()->get();

            return \Response::data(['token' => $token, 'openId' => $openId]);
        } catch(\Exception $exc) {
            return \Response::error('异常信息报错', 10100);
        }
        //设置消息开关
        $memberSwitchModel  = new \MemberSwitchModel();
        $memberSwitchMapper = MemberSwitchMapper::getInstance();
        $memberSwitchModel->setUid($id);
        $memberSwitchModel->setReceiver_inform(Lib\Consts::MEMBER_RECEIVER_INFORM);
        $memberSwitchModel->setInform_type(Lib\Consts::MEMBER_SHOW_INFORM);

        try {
            $memberSwitchMapper->insert($memberSwitchModel);
        } catch(\Exception $exc) {
            $errMsg = $exc->getMessage();
            return \Response::error($errMsg, 10100);
        }

        // 注册成功后, 即直接登录
        $userLib = \Lib\User::getInstance();
        $userLib->login($mobile, $password);
        $token = \Lib\Token::getInstance()->get();

        return \Response::data(['token' => $token], '完成注册');

    }

    /**
     * @desc 忘记密码
     *
     * @return false
     */
    public function resetPasswordAction() {
        $request  = $this->getRequest();
        $mobile   = (string)$request->get('mobile');
        $password = (string)$request->get('password');
        $code     = (string)$request->get('code');

        if(empty($mobile)) {
            return \Response::error('手机号码不能为空', 10111);
        }

        if(empty($password)) {
            return \Response::error('密码不能为空', 10112);
        }

        if(empty($code)) {
            return \Response::error('验证码不能为空, 请重新输入', 10108);
        }

        if(!\Lib\Is::mobileNum($mobile)) {
            return \Response::error('手机号码格式错误', 10107);
        }

        $verifyCode = \Lib\Msgcode::verify($mobile, 'lost_password', $code);

        if(!$verifyCode) {
            return \Response::error('验证码错误', 10109);
        }

        $encryptPassword = \Lib\Passwd::encrypt($password);
        $memberMapper    = MemberMapper::getInstance();
        $memberModel     = $memberMapper->findByMobile($mobile);

        if(!$memberModel instanceof \MemberModel) {
            return \Response::error('Invalid Mobile', 10113);
        }

        if(empty($memberModel->getMobile())) {
            return \Response::error('手机号不存在, 请重新输入', 10103);
        }

        // 只更改密码字段
        $memberModel->setPassword($encryptPassword);

        try {
            $rows = $memberMapper->update($memberModel, ['id' => $memberModel->getId()]);
            return $rows > 0 ? \Response::data(null) : \Response::error('重置密码失败', 10119);
        } catch(\Exception $exc) {
            return \Response::error('异常信息报错', 10100);
        }
    }

    /**
     * @desc 修改密码
     *
     * @return false
     */
    public function changePasswordAction() {
        $request     = $this->getRequest();
        $uid         = \Lib\User::getInstance()->id();
        $password    = $request->get('password', 12345);
        $newPassword = $request->get('newPassword', 123456);

        if(empty($password)) {
            return \Response::error('密码不能为空', 10112);
        }

        if(empty($newPassword)) {
            return \Response::error('新密码不能为空', 10108);
        }

        $memberMapper = MemberMapper::getInstance();
        $model        = $memberMapper->findById($uid);

        if(!$model instanceof \MemberModel || \Lib\Passwd::valid($password, $model->getPassword()) === false) {
            return \Response::error('手机号或密码错误', 10104);
        }

        $encryptPassword = \Lib\Passwd::encrypt($newPassword);

        $data = [
            'password' => $encryptPassword,
        ];

        try {
            $rows = $memberMapper->update($data, ['id' => $uid]);
            return $rows > 0 ? \Response::data(null) : \Response::error('修改密码失败', 10120);
        } catch(\Exception $exc) {
            return \Response::error('异常信息报错', 10100);
        }
    }

    /**
     * @desc 登录功能
     *
     * @return false
     */
    public function loginAction() {
        \Lib\User::getInstance()->login();
        $token = \Lib\Token::getInstance()->get();

        return \Response::data(['token' => $token], '登录成功');
    }

    /**
     * @desc 退出登录
     *
     * @param $memberId
     */
    public function logoutAction() {
        $request = $this->getRequest();
        $token   = (string)$request->get('token');
        $uid     = \Lib\User::getInstance()->id();
        \Lib\Token::getInstance()->delete($token, ['uid' => $uid]);

        return \Response::data(null, '退出登录成功');
    }

    /**
     * @desc 完善用户资料
     *
     * @return false
     */
    public function completeInfoAction() {
        $request        = $this->getRequest();
        $uid            = \Lib\User::getInstance()->id();
        $nickName       = (string)$request->get('nickName');
        $mainGame       = (string)$request->get('mainGame');
        $gameZone       = (string)$request->get('gameZone');
        $gameAccount    = (string)$request->get('gameId');
        $goodRole       = (string)$request->get('goodRole');
        $quotations     = (string)$request->get('quotations');
        $elseGame       = (string)$request->get('elseGame');
        $characterSign  = (string)$request->get('characterSign');
        $birthday       = (string)$request->get('birthday');
        $profession     = (string)$request->get('profession');
        $birthplace     = (string)$request->get('birthplace');
        $hobby          = (string)$request->get('hobby');
        $relationStatus = (string)$request->get('relationStatus');
        $appearance     = (string)$request->get('appearance');
        $loveTimes      = (string)$request->get('loveTimes');
        $monthIncome    = (string)$request->get('monthIncome');
        $housing        = (string)$request->get('housing');
        $school         = (string)$request->get('school');
        $company        = (string)$request->get('company');

        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return \Response::error('Invalid Uid', 10110);
        }

        if(!empty($nickName)) {
            $memberModel->setNick_name(urlencode($nickName));
            $memberModel->setLetter(\Lib\Pinyin::to_first($nickName));
        }

        if(!empty($mainGame)) {
            $memberModel->setMain_game($mainGame);
        }

        if(!empty($gameZone)) {
            $memberModel->setGame_zone($gameZone);
        }

        if(!empty($gameAccount)) {
            $memberModel->setGame_account($gameAccount);
        }

        if(!empty($goodRole)) {
            $memberModel->setGood_role($goodRole);
        }

        if(!empty($quotations)) {
            $memberModel->setQuotations($quotations);
        }

        if(!empty($elseGame)) {
            $memberModel->setElse_game($elseGame);
        }

        if(!empty($characterSign)) {
            $memberModel->setCharacter_sign($characterSign);
        }

        if(!empty($relationStatus)) {
            $memberModel->setRelation_status($relationStatus);
        }

        if(!empty($hobby)) {
            $memberModel->setHobby($hobby);
        }

        if(!empty($birthday)) {
            $birthday = strtotime($birthday);
            $memberModel->setBirthday($birthday);
        }

        if(!empty($profession)) {
            $memberModel->setProfession($profession);
        }

        if(!empty($birthplace)) {
            $memberModel->setBirthplace($birthplace);
        }

        if(!empty($appearance)) {
            $memberModel->setAppearance($appearance);
        }

        if(!empty($loveTimes)) {
            $memberModel->setLove_times($loveTimes);
        }

        if(!empty($monthIncome)) {
            $memberModel->setMonth_income($monthIncome);
        }

        if(!empty($housing)) {
            $memberModel->setHousing($housing);
        }

        if(!empty($school)) {
            $memberModel->setSchool($school);
        }

        if(!empty($company)) {
            $memberModel->setCompany($company);
        }

        try {
            $rows = $memberMapper->update($memberModel, ['id' => $uid]);
            return $rows > 0 ? \Response::data(null) : \Response::error('资料更新失败', 10121);
        } catch(\Exception $exc) {
            return \Response::error('异常信息报错', 10100);
        }
    }

    /**
     * @des 认证
     *
     * @return false
     */
    public function authenticationAction() {
        $uid     = \Lib\User::getInstance()->id();
        $request = $this->getRequest();
        $idNum   = (string)$request->get('idNum');
        $name    = (string)$request->get('name');

        if(empty($idNum) || !\Lib\IdCard::checkIdCard($idNum)) {
            return \Response::error('身份证号不能为空或不合法', 20501);
        }

        if(empty($name) || !\Lib\Verify::isCnName($name)) {
            return \Response::error('姓名不能为空', 20502);
        }


        $memberMapper       = MemberMapper::getInstance();
        $memberSwitchMapper = Mapper\MemberSwitchModel::getInstance();

        try {
            $memberMapper->update(['id_card' => $idNum, 'name' => $name], ['id' => $uid]);
            $memberSwitchMapper->update(['authentication' => \Lib\Consts::AUTHENTICATION], ['uid' => $uid]);

            return \Response::data(null, '认证成功');

        } catch(\Exception $exc) {
            $errMsg = $exc->getMessage();
            return \Response::error($errMsg, 10100);

        }

    }

    /**
     * @desc 取得用户信息
     *
     * @return false
     */
    public function memberInfoAction() {
        $uid          = \Lib\User::getInstance()->id();
        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return \Response::error('Invalid Uid', 10110);
        }

        $return = [
            [
                'nick_name'  => urldecode($memberModel->getNick_name()),
                'main_game'  => $memberModel->getMain_game(),
                'game_zone'  => $memberModel->getGame_zone(),
                'game_id'    => $memberModel->getGame_account(),
                'good_role'  => $memberModel->getGood_role(),
                'quotations' => $memberModel->getQuotations(),
                'else_game'  => $memberModel->getElse_game(),
            ],
            [
                'character_sign' => $memberModel->getCharacter_sign(),
                'birthday'       => date('Y-m-d', $memberModel->getBirthday()),
                'profession'     => $memberModel->getProfession(),
                'birthplace'     => $memberModel->getBirthplace(),
                'hobby'          => $memberModel->getHobby(),
            ],
            [
                'relation_status' => $memberModel->getRelation_status(),
                'appearance'      => $memberModel->getAppearance(),
                'love_times'      => $memberModel->getLove_times(),
                'month_income'    => $memberModel->getMonth_income(),
                'housing'         => $memberModel->getHousing(),
                'school'          => $memberModel->getSchool(),
                'company'         => $memberModel->getCompany(),
            ],
        ];

        return \Response::data($return);
    }

    /**
     * @desc 发生注册短信验证码
     *
     * @return false
     */
    public function sendRegisterMessageAction() {
        $request = $this->getRequest();
        $mobile  = (string)$request->get('mobile');

        if(empty($mobile)) {
            return \Response::error('手机号码不能为空', 10111);
        }

        if(!\Lib\Is::mobileNum($mobile)) {
            return \Response::error('手机号码格式错误', 10107);
        }

        $code = \Lib\Msgcode::create($mobile, 'register');

        \Lib\Queue::push('sms', [
            'mobile'  => $mobile,
            'content' => $code,
        ]);

        return \Response::data(['code' => $code]);
    }

    /**
     * @desc 发生忘记密码短信验证码
     *
     * @return false
     */
    public function sendLostPwdMessageAction() {
        $request = $this->getRequest();
        $mobile  = (string)$request->get('mobile');

        if(empty($mobile)) {
            return \Response::error('手机号码不能为空', 10111);
        }

        if(!\Lib\Is::mobileNum($mobile)) {
            return \Response::error('手机号码格式错误', 10107);
        }

        $code = \Lib\Msgcode::create($mobile, 'lost_password');

        \Lib\Queue::push('sms', [
            'mobile'  => $mobile,
            'content' => sprintf(\Lib\Msg::MESSAGE_LOST_PASSWORD, $code),
        ]);

        return \Response::data(['code' => $code]);
    }

    public function getMemberLocationAction() {
        $request   = $this->getRequest();
        $uid       = \Lib\User::getInstance()->id();
        $longitude = (float)$request->get('longitude', 0);
        $latitude  = (float)$request->get('latitude', 0);

        if($longitude > 180 || $longitude < 0 || $latitude > 90 || $longitude < 0) {
            return \Response::error('经纬度数据有误, 请重新获取', 10118);
        }

        $memberMapper = MemberMapper::getInstance();
        $memberModel  = $memberMapper->findById($uid);

        if(!$memberModel instanceof \MemberModel) {
            return \Response::error('Invalid Uid', 10110);
        }

        $numConversion = \Lib\Consts::LATITUDE_LONGITUDE_CONVERSION;
        $memberModel->setLongitude($longitude * $numConversion);
        $memberModel->setLatitude($latitude * $numConversion);

        try {
            $rows = $memberMapper->update($memberModel, ['id' => $uid]);
            return $rows > 0 ? \Response::data(null) : \Response::error('获取当前位置失败', 10122);
        } catch(\Exception $exc) {
            return \Response::error('异常信息报错', 10100);
        }
    }

    /**
     * @desc 根据两点间的经纬度计算距离
     * @param $lng1 float 经度值
     * @param $lat1 float 纬度值
     * @param $lng2 float
     * @param $lat2 float
     * @return float
     */
    public function getDistanceAction($lng1, $lat1, $lng2, $lat2) {
        $earthRadius = \Lib\Consts::EARTH_RADIUS;
        $lat1        = ($lat1 * pi()) / 180;
        $lng1        = ($lng1 * pi()) / 180;
        $lat2        = ($lat2 * pi()) / 180;
        $lng2        = ($lng2 * pi()) / 180;

        $calcLongitude      = $lng2 - $lng1;
        $calcLatitude       = $lat2 - $lat1;
        $stepOne            = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
        $stepTwo            = 2 * asin(min(1, sqrt($stepOne)));
        $calculatedDistance = $earthRadius * $stepTwo;

        return round($calculatedDistance);
    }

    /**
     * @desc 附近的人列表
     * @return false
     */
    public function nearByListAction() {
        $request     = $this->getRequest();
        $longitude   = $request->get('longitude', 0);
        $latitude    = $request->get('latitude', 0);
        $return      = [];
        $distanceArr = [];

        if($longitude < 0 || $latitude < 0 || $longitude > 180 || $latitude > 90) {
            return \Response::error('经纬度数据有误, 请重新获取', 10118);
        }

        $memberMapper = MemberMapper::getInstance();
        $llValue      = \Lib\Consts::LATITUDE_LONGITUDE_1KM;
        $conversion   = \Lib\Consts::LATITUDE_LONGITUDE_CONVERSION;

        $where = [
            'status'         => 1,
            'longitude <= ?' => $longitude * $conversion + $llValue,
            'longitude >= ?' => $longitude * $conversion - $llValue,
            'latitude <= ?'  => $latitude * $conversion + $llValue,
            'latitude >= ?'  => $latitude * $conversion - $llValue,
        ];

        $models = $memberMapper->fetchAll($where, 'id');

        foreach($models as $model) {
            $arr             = $model->toArray();
            $longitudeTo     = $model->getLongitude() / $conversion;
            $latitudeTo      = $model->getLatitude() / $conversion;
            $distance        = $this->getDistanceAction($longitude, $latitude, $longitudeTo, $latitudeTo);
            $arr['distance'] = $distance;
            $distanceArr[]   = $distance;
            $return[]        = $arr;
        }

        array_multisort($distanceArr, SORT_ASC, $return);

        return \Response::data($return, '获取附近的人');
    }

    /**
     * @desc openId生成
     *
     * @return string
     */
    protected function createOpenId($nickname, $registerTime) {
        $randNum = dechex(mt_rand(0, 15));

        for($i = 0; $i < 3; ++$i) {
            $randNum .= dechex(mt_rand(0, 15));
        }

        $salt = \Yaf\Registry::get('config')->get('resources.salt.openid');

        return sha1($nickname . $registerTime . uniqid($randNum) . $salt);
    }


}
